/*
 *	create by senllang 2023/5/3
 *  mail : study@senllang.onaliyun.com
 *	
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include <string.h>
#include "ipc_mutex.h"
#include "ipc_shmem.h"
#include "process.h"
#include "ipc_rwlock.h"

static unsigned long END_VALUE = 0xFFFF;

int main(int argc, char *argv[])
{
	int NumProcess = 0;
	int NumLocks = 0;
	char *pMemAddr = NULL;
	int SharedMemSie = 0;
	unsigned long *pValue = NULL;

	/* Initialize environment */
	if(argc < 2)
	{
		printf("argc is Invalid\n");
		return -1;
	}
	
	NumProcess = atoi(argv[1]);
	NumLocks = atoi(argv[2]);
	
	// SharedMemSie = GetMutexSize(NumLocks) + sizeof(unsigned long);
	SharedMemSie = GetRwlockSize(NumLocks) + sizeof(unsigned long);
	CreateShMem(&pMemAddr, SharedMemSie);
	// InitMutex(pMemAddr, NumLocks);
	Initrwlock(pMemAddr, NumLocks);

	pValue = (unsigned long *)(pMemAddr + GetRwlockSize(NumLocks));
	*pValue = 0;

	CreateSubProcess(NumProcess, argc, argv);
	
	/* waiting subprocess exit */
	WaitSubProcessComplete();
	
	/* Destroy environment */
	DestroyMutex(pMemAddr, NumLocks);
	DestroyShMem(1);
	
	return 0;
}

/* 全局变量，记录共享内存的信息 */
extern stShMem shmemInfo;
/*
 * 进程任务处理主函数，此函数不会返回调用处
 *
 * create by senllang 2023/5/20
 *
 */
 int ProcessMain(int argc, char *argv[])
{
	int NumLocks = 0;
	unsigned long *pValue = NULL;
	char *pwlLockAddr = shmemInfo.pShMemStartAddr;
	int pid = getpid();
	int isEnd = 0;

	NumLocks = atoi(argv[2]);
	pValue = (unsigned long *)(pwlLockAddr + GetRwlockSize(NumLocks));

	printf("process running [%d]\n", pid);

	while(1)
	{
		if(processType)
		{
			Wrlock(pwlLockAddr);
			(*pValue)++;
		}
		else
		{
			sleep(1); // delay
			Rdlock(pwlLockAddr);
		}

		if(*pValue > END_VALUE)
			isEnd = 1;
		//sleep(1);
		printf("process-[%d] locktype[%s] value[%lu] \n", pid, processType? "wrlock":"rdlock", *pValue);

		RwlockUnlock(pwlLockAddr);

		if(isEnd)
			break;
	}
	return 0;
}

int ProcessMain_metux(int argc, char *argv[])
{
	int NumLocks = 0;
	unsigned long *pValue = NULL;
	char *pMutexAddr = shmemInfo.pShMemStartAddr;
	int pid = getpid();

	NumLocks = atoi(argv[2]);
	pValue = (unsigned long *)(pMutexAddr + GetMutexSize(NumLocks));

	printf("process running [%d]\n", pid);

	MutexLock(pMutexAddr);
	(*pValue)++;
	sleep(1);
	printf("process-[%d] value[%lu]\n", pid, *pValue);
	MutexUnlock(pMutexAddr);
	return 0;
}
